package com.cxz.kotlin.baselibs.ext

import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Point
import android.os.Build
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.ImageView
import androidx.annotation.FloatRange
import androidx.annotation.IntRange
import androidx.annotation.NonNull
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.BaseRequestOptions
import com.bumptech.glide.request.RequestOptions
import com.cxz.kotlin.baselibs.R

/**
 * 设置自适应高度的ImageView
 */
fun ImageView.setScaleImg(bitmap: Bitmap) {
    post {
        setImageBitmap(bitmap)
        /*
         * 获取ImageView中image的宽高
         * 注意：这里的宽高是Image原始的宽高，不是当前在ImageView中显示的宽高
         */
        val imgWidth = this.drawable.bounds.width()
        val imgHeight = this.drawable.bounds.height()

        // 获取ImageView中Image的变换矩阵
        val emptyMatrix = FloatArray(9)
        this.imageMatrix.getValues(emptyMatrix)

        // 分别从矩阵中获取X和Y的缩放系数
        val scaleX = emptyMatrix[0]
        val scaleY = emptyMatrix[4]

        // 计算Image在屏幕上实际绘制的宽高
        val realWidth = (imgWidth * scaleX).toInt()
        val realHeight = (imgHeight * scaleY).toInt()

        // 将ImageView的高度重新设置为ImageView中实际绘制的Image的高度，这样上下的留白就没有了，图片也可以完整显示了，不必
        // 刻意设置scaleType,使用默认的FIT_CENTER就好。
        val layoutParams: ViewGroup.LayoutParams = this.layoutParams
        layoutParams.height = realHeight
        this.layoutParams = layoutParams
    }
}

/**
 * 高效加载大型位图
 * https://developer.android.google.cn/topic/performance/graphics/load-bitmap
 * imageView.setImageBitmap(decodeSampledBitmapFromResource(resources, R.id.myimage, 100, 100))
 */
fun decodeSampledBitmapFromResource(
    res: Resources,
    resId: Int,
    reqWidth: Int,
    reqHeight: Int
): Bitmap {
    // First decode with inJustDecodeBounds=true to check dimensions
    return BitmapFactory.Options().run {
        inJustDecodeBounds = true
        BitmapFactory.decodeResource(res, resId, this)

        // Calculate inSampleSize
        inSampleSize = calculateInSampleSize(this, reqWidth, reqHeight)

        // Decode bitmap with inSampleSize set
        inJustDecodeBounds = false

        BitmapFactory.decodeResource(res, resId, this)
    }
}

private fun calculateInSampleSize(
    options: BitmapFactory.Options,
    reqWidth: Int,
    reqHeight: Int
): Int {
    // Raw height and width of image
    val (height: Int, width: Int) = options.run { outHeight to outWidth }
    var inSampleSize = 1

    if (height > reqHeight || width > reqWidth) {

        val halfHeight: Int = height / 2
        val halfWidth: Int = width / 2

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) {
            inSampleSize *= 2
        }
    }
    return inSampleSize
}


/**
 * 加载图片
 */
fun ImageView.loadImage(context: Context, path: String, placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean = false) {
    var options = getOptions(placeholder, useCache)
    Glide.with(context).load(path).apply(options).into(this)
}

/**
 * 加载圆形图片
 */
fun ImageView.loadCircleImage(context: Context, path: String, placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean = false) {
    var options = getOptions(placeholder, useCache)
    options.circleCrop()
    Glide.with(context).load(path).apply(options).into(this)
}

/**
 * 加载圆角图片
 */
fun ImageView.loadRoundCornerImage(context: Context, path: String, roundingRadius: Int = 20, placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean = false) {
    var options = getOptions(placeholder, useCache)
    Glide.with(context).load(path).apply(RequestOptions.bitmapTransform(RoundedCorners(roundingRadius))).apply(options).into(this)
}

/**
 * 取消加载
 */
fun ImageView.loadClear(context: Context) {
    Glide.with(context).clear(this)
}

/**
 * 按照图片的宽高比加载
 * 使用本属性的ImageView在xml布局中的width及height属性必须为WRAP_CONTENT
 * widthProportion 为相对于屏幕宽度的比例取值范围为0.0-1.0，当widthProportion=1.0时，ImageView的宽度为屏幕宽度
 * heightProportion为相对于图片宽度的显示比例
 */
fun ImageView.loadImageByProportion(@FloatRange(from = 0.0, to = 1.0) widthProportion: Float, heightProportion: Float) {
    this.adjustViewBounds = true
    var screenWidth = 0
    var wm: WindowManager = this.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    if (wm == null) {
        screenWidth = this.context.resources.displayMetrics.widthPixels - leftMargin - rightMargin
    } else {
        var point = Point()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            wm.defaultDisplay.getRealSize(point)
        } else {
            wm.defaultDisplay.getSize(point)
        }
        screenWidth = point.x - leftMargin - rightMargin
    }
    var para = this.layoutParams
    para.width = (screenWidth * widthProportion).toInt()
    para.height = ViewGroup.LayoutParams.WRAP_CONTENT
    layoutParams = para
    maxWidth = (screenWidth * widthProportion).toInt()
    maxHeight = (screenWidth * widthProportion * heightProportion).toInt()
    scaleType = ImageView.ScaleType.CENTER_CROP
}


private fun ImageView.getOptions(placeholder: Int = R.mipmap.ic_launcher, useCache: Boolean = false): RequestOptions {
    var options = RequestOptions()
    options.placeholder(placeholder)
    options.priority(Priority.HIGH)
    if (useCache)
        options.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
    return options
}



